Raphael.Chart.bar = Raphael.Chart.bar || {};
Raphael.Chart.bar.theme = {
              title : {
                    title : {style:{fill:"white","font-size":30}},
                    subtitle:{ style:{fill:"#aaa","font-size":12}}
                  },
              grid : {
                    display : true,
                    lines : {stroke : "white"},
                    interLines : {display : true,
                            style : { stroke : "white" , "stroke-width" : 0.1}
                            },
                    animation : {
                        animateIt : false,
                        ms : 2000,
                        style : "bounce"
                      }
                  },
              xaxis : {
                    display : true,
                    arrow : {display : true,double : false,width : 7,height:7,style:{fill:"white"}},
                    line : {stroke:"white","stroke-width":2} // style of the line
                  },
              transparentRect : {
                        display : false,
                        color : "#fff",
                        opacity : 0.7,
                        radius : 0
                        },
              background : {
                      display : true,
                      type : "image",
                      color : "#000",
                      "img-src" : "image",
                      "img-type" : "tile"
                    },
              yaxis : {
                    display : true,
                    arrow : {display : true,double : false,width : 7,height:7,style:{fill:"white"}},
                    line : {stroke:"white","stroke-width":2} // style of the line
                  },
              bars : {
                    vertical : true,
                    styles:[{fill:"rgba(255,0,9,0.15)",stroke:"none"},{fill:"45-#0f0-#000",stroke:"none"},{fill:"45-#00f-#000",stroke:"none"},{fill:"45-#aaf-#000",stroke:"none"}],
                    text : {displayValues : true,offset:15,styles:[{fill:"#f00",stroke:"none"},{fill:"#0f0",stroke:"none"},{fill:"#00f",stroke:"none"},{fill:"45-#aaf-#000",stroke:"none"}]},
                    animation : {
                        animateIt : true,
                        ms : 1000,
                        style : ">"
                      }
                  }
            };

Raphael.fn.barChart = function(labels,values,config,theme){
  // Container
  var container = config.chart.container,
    width = config.chart.width,
    height = config.chart.height,
    r = this,
    
    // General :
    htitle = config.general.htitle,
    hfooter = config.general.hfooter,
    wleft = config.general.wleft,
    wright = config.general.wright,
    
    // The grid and the bars :
    eps = config.container.eps,
    offset = config.container.offset,
    min = config.container.min,
    max = config.container.max,
    
    // The title : 
    title = config.title.title,
    subtitle = config.title.subtitle,
    
    // The theme : (all parameters are Not Required)
    th = $.extend(true,{},Raphael.Chart.bar.theme,theme);
    
  // The background :
  if(th.background.display){
    r.background(th.background);
  }
  
  // The transparent rectangle :
  if(th.transparentRect.display){
    r.transparentRect({x:wleft,y:htitle,width:width-wleft-wright,height:height-hfooter-htitle},th.transparentRect);
  }
  
  // The grid :
  if(th.grid.display){
    r.grid({x:wleft,y:htitle,width:width-wleft-wright,height:height-hfooter-htitle,xstep :(width-wleft-wright)/values[0].length,ystep : (height-hfooter-htitle)/values[0].length},th.grid);
  }
  
  // The Bars :
  var obj = {
        container : {cx:wleft,cy:htitle,cw:width-wleft-wright,ch:height-hfooter-htitle,offset:offset,eps:eps},
        data : {values :values, min : min , max : max }
      }
  r.bars(obj,th.bars,{});
  
  // The axisses
  if(th.xaxis.display){
    r.axis({x:wleft,y:height-hfooter,width:height-hfooter-htitle,rotate:-90},th.xaxis);
  }
  if(th.yaxis.display){
    r.axis({x:wleft,y:height-hfooter,width:width-wleft-wright},th.yaxis);
  }
  
  // Titles :
    // The title :
    r.text(width/2,htitle/3,config.title.title).attr(th.title.title.style);
    // The subtitle :
    r.text(width/2,2*htitle/3,config.title.subtitle).attr(th.title.subtitle.style);
  
  return r;
    
};


Raphael.fn.bar = function(obj,theme,events){
  var r = this ,
    set = r.set(),
    
    // container
      cx = obj.container.cx,
      cy = obj.container.cy,
      ch = obj.container.ch,
      cw = obj.container.cw,
      offset = obj.container.offset,
      eps = obj.container.eps,
      
    // data
      values = obj.data.values,
      min = obj.data.min,
      max = obj.data.max;
      
    
  set.barsset = r.set();
  set.textset = r.set();
  
  set.tracer = function(longueur,largeur){
    if(values[0] instanceof Array){
      // local variables
      var n = values[0].length,
        step = largeur/n;
      for(var i = 0 ; i < n ; i++){
        var pas = ( step - 2*offset + eps)/values.length;
        var gh = pas - eps;
        for(var j = 0 ; j < values.length ; j++){
          var wid = Math.min((values[j][i]-min)*longueur/(max-min),longueur);
          var bar = r.rect(cx,cy+j*pas+offset+i*step,wid,gh);
          if(theme.text.displayValues){
            var txt = r.text(cx+wid+theme.text.offset,cy+j*pas+offset+i*step+gh/2,values[j][i]);
          }
          if(theme.animation.animateIt){
            bar.attr({width:0}).animate({width:wid},theme.animation.ms,theme.animation.style);
            if(theme.text.displayValues){
              txt.attr({x:cx}).animate({x:cx+wid+theme.text.offset},theme.animation.ms,theme.animation.style);
            }
          }
          set.barsset.push(bar);
          set.textset.push(txt);
          
          // Themes :
          bar.attr(theme.styles[j]);
          txt.attr(theme.text.styles[j]);
        }
      }
    }
    else{
      var n = values.length,
        step = (largeur - 2*offset + eps)/n;
        
      for(var i = 0 ; i < n ; i++){
        var gh = step - eps;
        var wid = Math.min((values[i]-min)*longueur/(max-min),longueur);
        var bar = r.rect(cx,cy+offset+i*step,wid,gh);
        if(theme.text.displayValues){
          var txt = r.text(cx+wid+theme.text.offset,cy+offset+i*step+gh/2,values[i]);
        }
        if(theme.animation.animateIt){
          bar.attr({width:0}).animate({width:wid},theme.animation.ms,theme.animation.style);
          if(theme.text.displayValues){
            txt.attr({x:0}).animate({x:cx+wid+theme.text.offset},theme.animation.ms,theme.animation.style);
          }
        }
        set.barsset.push(bar);
        set.textset.push(txt);
        
        // Themes :
        set.barsset.attr(theme.styles[0]);
        set.textset.attr(theme.text.styles[0]);
      }
    }
  }
  
  
  // Horizental
  if(!theme.vertical){
    var delta = (ch-cw)/2;
    set.tracer(ch,cw);
    set.barsset.rotate(-90,(cx+cw/2),(cy+ch/2));
    set.barsset.translate(delta,delta);
    set.textset.rotate(-90,(cx+cw/2),(cy+ch/2));
    set.textset.translate(delta,0);
    set.push(set.barsset,set.textset);
  }
  
  else{
    set.tracer(cw,ch);
    set.push(set.barsset,set.textset);
  }
  
  
  return set;
}


/**
 * Sets the the theme of the graph with a theme object given in parameter
 * @param {object} theme 
 */
Raphael.Chart.bar.setTheme = function(theme){
            var origin = this.theme;
            this.theme = $.extend(true,origin,theme);
          };

/**
 * Loads the theme from the specified file.
 * @param {Object} path - the path of the file.
 */
Raphael.Chart.bar.loadThemeFromFile = function(path){
          if(validExtension(path,['.wcs'])){
            var origin = this.theme;
            var theme;
            $.ajax({
              url: path,
              dataType: 'json',
              async : false,
              success: function(data){theme = data;},
              error : function(err){console.warn("Can not find the file : " + path);}
            });
            this.theme = $.extend(true,origin,theme);
          }
          else {
            console.warn("The file " + path + " is invalid!");
          }
};